/*
 * @Description: 地图选择组件
 * @Author: Zhanghan
 * @Date: 2025-03-24 14:02:54
 * @LastEditTime: 2025-03-25 21:36:13
 * @LastEditors: Zhanghan
 */
import { Modal, Button, message, Input, Spin } from "antd";
import {
  useState,
  forwardRef,
  useImperativeHandle,
  useEffect,
  useRef,
} from "react";
import positionIcon from "@/assets/images/position.png";
import { LoadBaiduMapScript } from "./map";
import "./index.less";

interface MapPropsType {
  onConfirm: (val) => void;
}

const MapChoice = forwardRef((props: MapPropsType, ref) => {
  const { Search } = Input;
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [searchValue, setSearchValue] = useState<string>("");
  const [loading, setLoading] = useState<boolean>(false);
  const [address, setAddress] =
    useState<string>("河南省郑州市二七区建设东路48号");
  const [lon, setLon] = useState<number>(113.65);
  const [lat, setLat] = useState<number>(34.76);

  // 使用 ref 存储地图相关对象（避免状态异步问题）
  const mapRef = useRef<any>(null);
  const pointRef = useRef<any>(null);
  const markerRef = useRef<any>(null);

  const showModal = () => {
    setIsModalOpen(true);
  };

  const handleOk = () => {
    setIsModalOpen(false);
    const data = { address, lon, lat };
    props.onConfirm(data); // 回调方式
  };

  const handleCancel = () => {
    setIsModalOpen(false);
  };

  useImperativeHandle(ref, () => ({
    showModal,
    handleOk,
    handleCancel,
  }));

  useEffect(() => {
    if (!isModalOpen) return;

    const init = async () => {
      await LoadBaiduMapScript();
      initMap({});
      await browserPosition();
    };

    init();
  }, [isModalOpen]);

  // 初始化地图
  const initMap = (record: any) => {
    const currentAddress = record.address || address || "郑州市";
    const currentLon = record?.coordinates?.lon ?? lon;
    const currentLat = record?.coordinates?.lat ?? lat;

    // 创建地图实例（使用 ref 存储）
    const mapInstance = new BMap.Map("container");
    const pointInstance = new BMap.Point(currentLon, currentLat);
    const myIcon = new BMap.Icon(positionIcon, new BMap.Size(23, 25));
    const markerInstance = new BMap.Marker(pointInstance, myIcon);

    // 存储到 ref
    mapRef.current = mapInstance;
    pointRef.current = pointInstance;
    markerRef.current = markerInstance;

    // 初始化地图设置
    mapInstance.centerAndZoom(pointInstance, 15);
    mapInstance.enableScrollWheelZoom();
    mapInstance.addOverlay(markerInstance);

    // 更新状态
    setAddress(currentAddress);
    setLon(currentLon);
    setLat(currentLat);

    // 绑定点击事件
    mapInstance.addEventListener("click", (e: any) => {
      const clickedPoint = new BMap.Point(e.point.lng, e.point.lat);
      mapInstance.centerAndZoom(clickedPoint, 15);
      pointRef.current = clickedPoint;

      // 逆地理编码获取地址
      const gc = new BMap.Geocoder();
      gc.getLocation(clickedPoint, (rs: any) => {
        if (rs?.address) {
          setAddress(rs.address);
          setLon(e.point.lng);
          setLat(e.point.lat);
          upInfoWindow(rs.address, e.point.lng, e.point.lat);
        }
      });
    });

    // 初始信息窗口
    upInfoWindow(currentAddress, currentLon, currentLat);
  };

  // 更新信息窗口
  const upInfoWindow = (address: string, lon: number, lat: number) => {
    if (!mapRef.current || !pointRef.current) return;

    const opts = {
      width: 250,
      height: 120,
      title: "经纬度",
    };
    const word = `<div>地址：${address}</div>
                  <div>经度：${lon}</div>
                  <div>纬度：${lat}</div>`;
    const infoWindow = new BMap.InfoWindow(word, opts);

    mapRef.current.openInfoWindow(infoWindow, pointRef.current);
    markerRef.current.addEventListener("click", () => {
      mapRef.current.openInfoWindow(infoWindow, pointRef.current);
    });
  };

  // 地址搜索
  const handleSearch = () => {
    if (!searchValue?.trim()) {
      message.warning("搜索框不能为空");
      return;
    }

    const myGeo = new BMap.Geocoder();
    myGeo.getPoint(searchValue.trim(), (point: any) => {
      if (point) {
        mapRef.current.centerAndZoom(point, 15);
        pointRef.current = point;
        setLon(point.lng);
        setLat(point.lat);

        const gc = new BMap.Geocoder();
        gc.getLocation(point, (rs: any) => {
          if (rs?.address) {
            setAddress(rs.address);
            upInfoWindow(rs.address, point.lng, point.lat);
          }
        });
      } else {
        message.warning("您选择的地址没有解析到结果！");
      }
    });
  };

  // 浏览器定位
  const browserPosition = async () => {
    setLoading(true);
    const geolocation = new BMap.Geolocation();

    geolocation.getCurrentPosition(async (r: any) => {
      if (r?.point) {
        const point = new BMap.Point(r.point.lng, r.point.lat);
        mapRef.current.centerAndZoom(point, 15);
        pointRef.current = point;

        const gc = new BMap.Geocoder();
        gc.getLocation(point, (rs: any) => {
          if (rs?.address) {
            setAddress(rs.address);
            setLon(r.point.lng);
            setLat(r.point.lat);
            upInfoWindow(rs.address, r.point.lng, r.point.lat);
          }
        });
      } else {
        message.error("定位失败，请手动输入经纬度");
      }
      setLoading(false);
    });
  };

  return (
    <>
      <div className="flex items-center">
        <div className="mr-2">位置</div>
        <Button type="primary" onClick={showModal}>
          唤醒地图
        </Button>
      </div>
      <Modal
        title="地图选择"
        open={isModalOpen}
        onOk={handleOk}
        onCancel={handleCancel}
        width={1000}
        okText={"确认"}
        cancelText={"关闭"}
      >
        <Spin spinning={loading}>
          <Search
            placeholder="请输入地址"
            value={searchValue}
            onChange={(e) => setSearchValue(e.target.value)}
            onSearch={handleSearch}
            style={{ width: "40%" }}
          />
          <div id="container" className="positionbox"></div>
        </Spin>
      </Modal>
    </>
  );
});

export default MapChoice;
